package com.theta.gateway.infra.common.exception.interceptor;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import com.theta.gateway.infra.common.base.Result;
import com.theta.gateway.infra.common.exception.BusinessException;
import com.theta.gateway.infra.common.exception.enums.ErrorEnum;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.nio.file.AccessDeniedException;
import java.util.Set;

@Slf4j
@RestControllerAdvice
public class GloablExceptionHandler {

    /**
     * 自定义异常
     */
    @SuppressWarnings("rawtypes")
	@ExceptionHandler(BusinessException.class)
    public Result handleBusinessException(BusinessException e){
        log.warn(e.getMessage(), e);
        return Result.error(e.getCode(), e.getMessage());
    }


    @SuppressWarnings("unchecked")
	@ExceptionHandler(Exception.class)
    public Result<String> exceptionHandler(Exception e) {
        Result<String> result = Result.error(e);
        if (e instanceof AccessDeniedException) {
            result.setCode(ErrorEnum.NO_AUTHORITY.getCode());
            result.setMsg(ErrorEnum.NO_AUTHORITY.getMessage());
        }else if (e instanceof ConstraintViolationException) {
            ConstraintViolationException constraintViolationException = (ConstraintViolationException) e;
            Set<ConstraintViolation<?>> violations = constraintViolationException.getConstraintViolations();
            StringBuilder strBuilder = new StringBuilder();
            for (ConstraintViolation<?> violation : violations) {
                strBuilder.append(violation.getMessage() + "\n");
            }
            result.setMsg(strBuilder.toString());
        } else if (e instanceof IllegalArgumentException) {
            result.setMsg("非法参数异常" + e.getMessage());
        } else if (e instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException exception = (MethodArgumentNotValidException) e;
            result.setMsg(exception.getBindingResult().getFieldError().getDefaultMessage());
        } else if (e instanceof UnknownHostException) {
            result.setMsg("未知主机" + e.getMessage());
        } else if (e instanceof SocketTimeoutException) {
            result.setCode(ErrorEnum.TIME_OUT.getCode());
            result.setMsg(ErrorEnum.TIME_OUT.getMessage());
        } else {
            result.setCode(ErrorEnum.UNKNOWN_ERROR.getCode());
            result.setMsg(ErrorEnum.UNKNOWN_ERROR.getMessage());
        }
        log.warn("exceptionHandler==>"+result.getCode() + ":" + result.getMsg(), e);
        return result;
    }

    private String extractErrorMsg(StringBuilder errorMsg) {
        String message = errorMsg.deleteCharAt(errorMsg.length() -1).toString();
        String msg = String.format(ErrorEnum.PARAMS_VALID_ERROR.getMessage(), message);
        log.error(msg);
        return msg;
    }
}
